#pragma once

#include <Arduino.h>
#include <ArduinoOTA.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <Ticker.h>

#include <ESP8266HTTPClient.h>
#include <ESP8266httpUpdate.h>

#include <FS.h>
#include <LittleFS.h>

#include "DebugLog.h"

#define BTN_NONE 0x00
#define BTN_CLICK 0x01
#define BTN_LONG 0x02

class ESP8266WSYBoot  {

public:
    static const uint8_t PIN_NONE = 255;
    ESP8266WSYBoot();

    void begin();
    void loop();

    void setLed(uint8_t pin, uint8_t on_val = HIGH);
    void ledOn();
    void ledOff();
    void ledFast();
    void ledSlow();
    void ledHeart();
    void ledWait();

    void setBtn(uint8_t pin, uint8_t down_val);
    uint8_t btnFlag();
    void btnClearFlag();

    void setDefaultWifi(String ssid, String pwd);
    void setWifi(String ssid, String pwd);
    void setHostname(String hostname);
    void savePassword(String password);
    String getPassword();
    bool isConnected();
    void disconnect();
    void update_begin(String binUrl);

private:
    uint8_t _led_pin;
    uint8_t _led_on_val;
    Ticker _led_ticker;
    uint32_t _led_pattern;

private:
    Ticker _btn_ticker;
    uint8_t _btn_pin;
    uint8_t _btn_down_val;
    uint8_t _btn_flag;

private:
    String _default_ssid = "";
    String _default_pwd = "";
    String _ssid = "";
    String _pwd = "";
    bool _wifi_state = false;
    ;

private:
    String _hostname;

private:
    void _setup_pins();

    void _led_start();
    void _led_stop();
    void _update_led_pattern(uint32_t pattern);
    static void _led_ticker_callback(ESP8266WSYBoot *self);

    void _btn_start();
    static void _btn_ticker_callback(ESP8266WSYBoot *self);

    void _wifi_reconnect();

    void _setup_littlefs();
    String _read_wifi_info();
    void _write_wifi_info(String ssid, String pwd);

    void _setup_OTA();
    void _setup_mDNS();

    /*
    static void _update_started(ESP8266WSYBoot *self);
    
    static void _update_finished(ESP8266WSYBoot *self);
    static void _update_progress(ESP8266WSYBoot *self,int cur, int total);
    static void _update_error(ESP8266WSYBoot *self,int err);
    */

private:
    static void _update_started(ESP8266WSYBoot *self);
    static void _update_finished(ESP8266WSYBoot *self);
    static void _update_progress(ESP8266WSYBoot *self, int cur, int total);
    static void _update_error(ESP8266WSYBoot *self, int err);
};
